﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;

namespace UFIDA.U8.YYNBJY.Operate
{
    public class TBGL_ACCVOUCH
    {
        public static string MKURL = ConfigurationManager.AppSettings["MKURL"].ToString();//MES接口地址
        public static string SECRET = ConfigurationManager.AppSettings["appcode"].ToString();
        public static string APPCODE = ConfigurationManager.AppSettings["appsecret"].ToString();
        public static string GL_ACCVOUCH(string filename, string date, string dbname, string cvouchid,string csign, bool ilog, bool iilog)
        {
            PUBMethod.PMethod.printmsgs(filename, "===[" + DateTime.Now.ToString() + "][" + dbname + "][" + filename + "]方法START===", true, ilog, iilog, System.Drawing.Color.Black);
            try
            {
                List<JSONDATA.GL_ACCVOUCH> lig = new List<JSONDATA.GL_ACCVOUCH>();
                string date1 = Convert.ToDateTime(date).AddMonths(2).ToString("yyyy-MM-dd");
                string where = " and 1=1 ";
                if (!string.IsNullOrEmpty(cvouchid))
                {
                    where += " and GL.ino_id='" + cvouchid + "'";
                }
                if (!string.IsNullOrEmpty(csign))
                {
                    where += " and GL.csign ='" + csign + "'";
                }
                string sql = @"SELECT  sub.ino_id,
                                       sub.csign,
                                       sub.isignseq,
                                       sub.iYPeriod,
                                       sub.tvouchtime
                                FROM
                                (
                                    SELECT GL.ino_id,
                                           GL.csign,
                                           GL.isignseq,
                                           GL.iYPeriod,
                                           CONVERT(varchar(16), max(GL.tvouchtime), 120) AS tvouchtime
                                    FROM gl_Accvouch GL
                                    WHERE isnull(GL.iflag,0)=0 and CONVERT(varchar(120), GL.dbill_date, 120) >= '" + date + @"' and CONVERT(varchar(120), GL.dbill_date, 120) < '" + date1 + @"' "+where+@"
                                      AND GL.ino_id IS NOT NULL
                                    GROUP BY GL.ino_id,
                                           GL.csign,
                                           GL.isignseq,
                                           GL.iYPeriod
                                ) AS sub
                                LEFT JOIN EF_GL_ACCVOUCH EF ON sub.csign = EF.CSIGN AND sub.iYPeriod = EF.iYPeriod AND sub.INO_ID = EF.INO_ID
                                WHERE (EF.TVOUVHTIME IS NULL OR CONVERT(varchar(16), sub.tvouchtime, 120) <> CONVERT(varchar(16), EF.TVOUVHTIME, 120))
                                GROUP BY sub.ino_id,
                                         sub.csign,
                                         sub.isignseq,
                                         sub.iYPeriod,
                                         sub.tvouchtime
                                ORDER BY sub.iYPeriod
                                OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY; ";
                PUBMethod.PMethod.printmsgs(filename + "SQL语句", "主表查询语句:" + sql, false, iilog, DBHelp.LogException.ilog, System.Drawing.Color.Red);
                DataTable dt = DBHelp.SQLHelper.GetDataTable(sql);
                if (dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        string ino_id = dt.Rows[i]["ino_id"].ToString();
                        csign = dt.Rows[i]["csign"].ToString();
                        string isignseq = dt.Rows[i]["isignseq"].ToString();
                        string iYPeriod = dt.Rows[i]["iYPeriod"].ToString();
                        string tvouchtime = dt.Rows[i]["tvouchtime"].ToString();
                        JSONDATA.GL_ACCVOUCH gl = new JSONDATA.GL_ACCVOUCH();
                        List<JSONDATA.LinesItem> lit = new List<JSONDATA.LinesItem>();
                        sql = @"select ino_id,csign,left(convert(nvarchar(120),dbill_date,20),7) iyperiod,
                                dbill_date,cbill,ccheck,cbook ,ccashier ,cdigest,gl.ccode,ccode_name,md_f,mc_f,md,mc,inid,nd_s,nc_s,
                                gl.cexch_name,nfrat,gl.cdept_id,cDepName,gl.cperson_id,cPersonName,
                                citem_class,citem_id,gl.csup_id,cVenName,gl.ccus_id,cCusName  
                                from GL_accvouch gl
                                left join code co on gl.ccode=co.ccode and gl.iyear=co.iyear
                                left join Vendor ve on gl.csup_id=ve.cVenCode
                                left join Person pe on gl.cperson_id=pe.cPersonCode
                                left join Department de on de.cDepCode=gl.cdept_id
                                left join Customer cu on gl.ccus_id=cu.cCusCode
                                where iYPeriod='" + iYPeriod + "' and csign='" + csign + "' and ino_id='" + ino_id + "' and isignseq='" + isignseq + "' ";
                        PUBMethod.PMethod.printmsgs(filename + "SQL语句", "明细表查询语句:" + sql, false, iilog, DBHelp.LogException.ilog, System.Drawing.Color.Red);
                        DataTable dts = DBHelp.SQLHelper.GetDataTable(sql);
                        decimal total = 0;
                        for (int j = 0; j < dts.Rows.Count; j++)
                        {

                            if (j == 0)
                            {
                                gl.voucherType = dts.Rows[0]["csign"].ToString();
                                gl.voucherPeriod = dts.Rows[0]["iyperiod"].ToString();
                                gl.voucherNo = dts.Rows[0]["ino_id"].ToString();
                                gl.accountSetNo = "008";
                                gl.businessEntityCode = "";
                                gl.voucherId = "008" + "-" + dts.Rows[0]["iyperiod"].ToString() + dts.Rows[0]["csign"].ToString() + "-" + dts.Rows[0]["ino_id"].ToString();
                                gl.businessEntityName = "杭州前进齿轮箱集团股份有限公司";
                                gl.voucherDate = dts.Rows[0]["dbill_date"].ToString();
                                gl.preparedBy = dts.Rows[0]["cbill"].ToString();
                                gl.approvedBy = dts.Rows[0]["ccheck"].ToString();
                                gl.@operator = dts.Rows[0]["ccheck"].ToString();
                                gl.reviewer = dts.Rows[0]["cbook"].ToString();
                                gl.cashier = dts.Rows[0]["ccashier"].ToString();
                                lig.Add(gl);
                            }
                            JSONDATA.LinesItem jli = new JSONDATA.LinesItem();
                            jli.voucherAbstract = dts.Rows[j]["cdigest"].ToString();
                            jli.subjectCode = dts.Rows[j]["ccode"].ToString();
                            jli.subjectName = dts.Rows[j]["ccode_name"].ToString();
                            decimal md = Convert.ToDecimal(dts.Rows[j]["md"].ToString());
                            if (md > 0)
                            {
                                jli.originalAmount = dts.Rows[j]["md_f"].ToString();
                            }
                            decimal mc = Convert.ToDecimal(dts.Rows[j]["mc"].ToString());
                            if (mc > 0)
                            {
                                jli.originalAmount = dts.Rows[j]["mc_f"].ToString();
                            }
                            total += Convert.ToDecimal(md) + Convert.ToDecimal(mc);
                            jli.debitAmount = md.ToString();
                            jli.creditAmount = mc.ToString();
                            jli.entrySequenceNo = dts.Rows[j]["inid"].ToString();
                            string inid = dts.Rows[j]["inid"].ToString();
                            string nd_s = dts.Rows[j]["nd_s"].ToString();
                            string nc_s = dts.Rows[j]["nc_s"].ToString();
                            if (!string.IsNullOrEmpty(nd_s))
                            {
                                jli.quantity = nd_s;
                            }
                            if (!string.IsNullOrEmpty(nc_s))
                            {
                                jli.quantity = nc_s;
                            }
                            jli.currency = dts.Rows[j]["cexch_name"].ToString();
                            jli.exchangeRate = dts.Rows[j]["nfrat"].ToString();
                            jli.deptCode = dts.Rows[j]["cdept_id"].ToString();
                            jli.deptName = dts.Rows[j]["cDepName"].ToString();

                            jli.employeeCode = dts.Rows[j]["cperson_id"].ToString();
                            jli.employeeName = dts.Rows[j]["cPersonName"].ToString();
                            string citemclass = dts.Rows[j]["citem_class"].ToString();
                            string citem_id = dts.Rows[j]["citem_id"].ToString();

                            jli.projectCode = citem_id;
                            if (!string.IsNullOrEmpty(citemclass) && !string.IsNullOrEmpty(citem_id))
                            {
                                jli.projectName = GetItemName(citemclass, citem_id);
                            }
                            jli.supplierCode = dts.Rows[j]["csup_id"].ToString();
                            jli.supplierName = dts.Rows[j]["cVenName"].ToString();
                            jli.merchantCode = dts.Rows[j]["ccus_id"].ToString();
                            jli.merchantName = dts.Rows[j]["cCusName"].ToString();
                            string cashcode = "", cashname = "";
                            GTECASHITEM(inid, ino_id, isignseq, iYPeriod, out cashcode, out cashname);
                            jli.cashFlowCode = cashcode;
                            jli.cashFlowName = cashname;
                            lit.Add(jli);

                        }
                        gl.total = total.ToString();
                        gl.lines = lit;

                    }
                    string json = JsonConvert.SerializeObject(lig);
                    PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用每刻接口传递JSON：" + json, false, ilog, iilog, System.Drawing.Color.Red);
                    string entCode = "", tokenId = "";
                    string[] AccessToken = GetAccessToken();
                    if (!string.IsNullOrEmpty(AccessToken[0]))
                    {
                        //entCode = AccessToken[0];
                        tokenId = AccessToken[0];
                        string Vurl = MKURL + "/open/voucher/v3/";
                        PUBMethod.PMethod.printmsgs(filename, "调用接口地址:" + Vurl, true, iilog, DBHelp.LogException.ilog, System.Drawing.Color.Red);
                        PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]获取到的TOKEN：" + tokenId, false, ilog, iilog, System.Drawing.Color.Red);
                        string res = PUBMethod.PMethod.MKCreatePostHttpResponses(Vurl, entCode, tokenId, json, null);
                        PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用每刻接口返回JSON：" + res, false, ilog, iilog, System.Drawing.Color.Red);
                        if (!string.IsNullOrEmpty(res))
                        {
                            if (res.Substring(0, 5) != "false")
                            {
                                JSONDATA.RESGL_ACCVOUCH jre = JsonConvert.DeserializeObject<JSONDATA.RESGL_ACCVOUCH>(res);
                                string code = jre.code;
                                if (code == "0")
                                {
                                    string succ = jre.data.successAmount;
                                    List<string> lis = new List<string>();
                                    for (int i = 0; i < dt.Rows.Count; i++)
                                    {
                                        string ino_id = dt.Rows[i]["ino_id"].ToString();
                                        csign = dt.Rows[i]["csign"].ToString();
                                        string isignseq = dt.Rows[i]["isignseq"].ToString();
                                        string iYPeriod = dt.Rows[i]["iYPeriod"].ToString();
                                        string tvouchtime = dt.Rows[i]["tvouchtime"].ToString();
                                        //lis.Add("delete from EF_GL_ACCVOUCH where CSIGN='" + csign + "' and INO_ID='" + ino_id + "' and ISIGNSEQ='" + isignseq + "' and IYPERIOD='" + iYPeriod + "'");
                                        //DBHelp.SQLHelper.ExecuteSqlTran(lis);
                                        //lis.Clear();
                                        PUBMethod.PMethod.printmsgs(filename, "["+iYPeriod+"]凭证["+csign+"]["+ino_id+"]传递成功!", true, ilog, iilog, System.Drawing.Color.Green);
                                        int ro = Convert.ToInt32(DBHelp.SQLHelper.GetString("select count(*) from EF_GL_ACCVOUCH where CSIGN='" + csign + "' and INO_ID='" + ino_id + "' and ISIGNSEQ='" + isignseq + "' and IYPERIOD='" + iYPeriod + "'"));
                                        if (ro > 0)
                                        {

                                            lis.Add("delete from EF_GL_ACCVOUCH where CSIGN='" + csign + "' and INO_ID='" + ino_id + "' and ISIGNSEQ='" + isignseq + "' and IYPERIOD='" + iYPeriod + "'");
                                            lis.Add("insert into EF_GL_ACCVOUCH(CSIGN,INO_ID,ISIGNSEQ,TVOUVHTIME,IYPERIOD,TBDATE) values('" + csign + "','" + ino_id + "','" + isignseq + "','" + tvouchtime + "','" + iYPeriod + "',GETDATE())");
                                        }
                                        else
                                        {
                                            lis.Add("insert into EF_GL_ACCVOUCH(CSIGN,INO_ID,ISIGNSEQ,TVOUVHTIME,IYPERIOD,TBDATE) values('" + csign + "','" + ino_id + "','" + isignseq + "','" + tvouchtime + "','" + iYPeriod + "',GETDATE())");
                                        }
                                    }
                                    DBHelp.SQLHelper.ExecuteSqlTran(lis);
                                    PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用每刻接口传递成功[" + succ + "]条", true, ilog, iilog, System.Drawing.Color.Red);
                                }
                                else
                                {
                                    int row = jre.errData.Count;
                                    for (int k = 0; k < row; k++)
                                    {
                                        string voucherNo = jre.errData[k].voucherNo;
                                        string voucherPeriod = jre.errData[k].voucherPeriod;
                                        string voucherType = jre.errData[k].voucherType;
                                        string errorMsg = jre.errData[k].errorMsg;
                                        PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]会计期间[" + voucherPeriod + "]凭证号[" + voucherType + "-" + voucherNo + "]传递失败,原因[" + errorMsg + "]", true, ilog, iilog, System.Drawing.Color.Red);
                                    }


                                }
                            }
                            else
                            {
                                PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用接口异常" + res, true, ilog, iilog, System.Drawing.Color.Red);
                            }
                        }
                        else
                        {
                            PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用每刻接口返回空值!", true, ilog, iilog, System.Drawing.Color.Red);
                        }
                    }
                    else
                    {
                        PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]调用每刻接口未返回TOKEN!", true, ilog, iilog, System.Drawing.Color.Red);
                    }
                }
                else
                {
                    PUBMethod.PMethod.printmsgs(filename, "没有需要同步的凭证数据", true, ilog, iilog, System.Drawing.Color.Red);
                }

            }
            catch (Exception ex)
            {
                PUBMethod.PMethod.printmsgs(filename, "[" + dbname + "][" + filename + "]BUG" + ex.Message, true, true, iilog, System.Drawing.Color.Red);
            }
            PUBMethod.PMethod.printmsgs(filename, "===[" + DateTime.Now.ToString() + "][" + dbname + "][" + filename + "]方法E N D===", true, ilog, iilog, System.Drawing.Color.Black);
            return "";
        }

        public static string GetItemName(string citemclass, string citemcode)
        {
            string sql;
            if (citemclass == "ch")
            {
                sql = "select cinvname from inventory where cinvcode='" + citemcode + "'";
            }
            else
            {
                sql = "select citemname from fitemss" + citemclass + " where citemcode='" + citemcode + "'";
            }
            return DBHelp.SQLHelper.GetString(sql);
        }

        public static void GTECASHITEM(string inid, string iNo_id, string iSignSeq, string iYPeriod, out string cashcode, out string cashname)
        {
            cashname = "";
            string sql = "select cCashItem from GL_CashTable where inid='" + inid + "' and iNo_id='" + iNo_id + "' and iSignSeq='" + iSignSeq + "' and iYPeriod='" + iYPeriod + "'";
            cashcode = DBHelp.SQLHelper.GetString(sql);
            if (!string.IsNullOrEmpty(cashcode))
            {
                cashname = DBHelp.SQLHelper.GetString("select citemname from fitemss98 where citemcode='" + cashcode + "' ");
            }
        }

        public static string[] GetAccessToken()
        {
            string[] AccessToken = new string[2];
            if (!string.IsNullOrEmpty(MKURL))
            {
                string url = "" + MKURL + "/open/auth/login";
                DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                string secret = SECRET;
                long timestamp = (long)((DateTime.UtcNow - Jan1st1970).TotalMilliseconds);
                string appcode = APPCODE;
                string ssoToken = SHA256(secret + ":" + appcode + ":" + timestamp);
                //参数p
                string parameters = "{\"userCode\":\"" + appcode + "\",\"secretToken\":\"" + ssoToken + "\",\"timestamp\":\"" + timestamp.ToString() + "\"}";
                PUBMethod.PMethod.printmsgs("鉴权接口", "接口地址:" + url, false, DBHelp.LogException.ilog, true, System.Drawing.Color.Red);
                PUBMethod.PMethod.printmsgs("鉴权接口", "调用接口传递:" + parameters, false, DBHelp.LogException.ilog, true, System.Drawing.Color.Red);
                string tokenjson = CreatePostHttpResponse(url, parameters, null);
                PUBMethod.PMethod.printmsgs("鉴权接口", "接口返回JSON:" + tokenjson, false, DBHelp.LogException.ilog, true, System.Drawing.Color.Red);
                JavaScriptSerializer js = new JavaScriptSerializer();   //实例化一个能够序列化数据的类
                JSONDATA.TokenJson list = js.Deserialize<JSONDATA.TokenJson>(tokenjson);    //将json数据转化为对象类型并赋值给list
                if (list.code == "200")
                {
                    //AccessToken[0] = list.data.entCode;
                    AccessToken[0] = list.data.token;
                    return AccessToken;
                }
                else
                    return AccessToken;
            }
            else
                return AccessToken;
        }

        //SHA256加密
        public static string SHA256(string str)
        {
            byte[] SHA256Data = Encoding.UTF8.GetBytes(str);

            SHA256Managed Sha256 = new SHA256Managed();
            byte[] by = Sha256.ComputeHash(SHA256Data);

            return BitConverter.ToString(by).Replace("-", "").ToLower(); //64
        }

        // long --> DateTime
        public static DateTime ConvertLongToDateTime(long d)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(d + "0000");
            TimeSpan toNow = new TimeSpan(lTime);
            DateTime dtResult = dtStart.Add(toNow);
            return dtResult;
        } //open/voucher/v3/

        /// 创建POST方式的HTTP请求  
        public static string CreatePostHttpResponse(string url, string parameters, CookieCollection cookies)
        {
            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            request.Method = "POST";
            //request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            request.ContentType = "application/json";

            if (cookies != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(cookies);
            }

            byte[] data = Encoding.ASCII.GetBytes(parameters.ToString());

            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }

            string[] values = request.Headers.GetValues("Content-Type");
            Stream myResponseStream = request.GetResponse().GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }
    }
}
